home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 001-025 / scopedisk9 / dmouse106 / dmouse-handler.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  9KB  |  349 lines

  1.  
  2.  
  3. /*
  4.  *  DMOUSE-HANDLER.C        compile 32 bit integers (+L)
  5.  *                AZTEC COMPILATION
  6.  *  18 May 1988
  7.  */
  8.  
  9. #include "dmouse.h"
  10.  
  11. #define IBASE IntuitionBase
  12.  
  13. DMS    *Dms;
  14. struct IntuitionBase *IntuitionBase;
  15. struct GfxBase         *GfxBase;
  16. long             *LayersBase;
  17.  
  18. NS    Ns = {    0, 0, 64, -1, 1, -1, -1, 0, CUSTOMSCREEN|SCREENQUIET };
  19.  
  20. IE *handler();
  21.  
  22. _main()
  23. {
  24.     register DMS *dms;
  25.     IOR  *ior;
  26.     INT addhand;
  27.  
  28.     {
  29.     register PROC *proc = (PROC *)FindTask(NULL);
  30.     proc->pr_ConsoleTask = NULL;
  31.     }
  32.     dms = Dms = FindPort(PORTNAME);
  33.     if (!dms)
  34.     _exit(0);
  35.     dms->Port.mp_Flags = PA_SIGNAL;
  36.     dms->Port.mp_SigBit = AllocSignal(-1);
  37.     dms->Port.mp_SigTask = FindTask(NULL);
  38.     dms->HandTask = dms->Port.mp_SigTask;
  39.     ior = CreateStdIO(&dms->Port);
  40.     IntuitionBase = OpenLibrary("intuition.library", 0);
  41.     GfxBase = OpenLibrary("graphics.library", 0);
  42.     LayersBase = OpenLibrary("layers.library", 0);
  43.  
  44.     if (!IntuitionBase || !GfxBase || !LayersBase)
  45.     goto startupfail;
  46.     addhand.is_Node.ln_Pri = 51;
  47.     addhand.is_Code = (FPTR)handler;
  48.     addhand.is_Data = NULL;
  49.  
  50.     if (OpenDevice("input.device", 0, ior, 0)) {
  51.     goto startupfail;
  52.     } else {
  53.     SCR *scr = NULL;
  54.     uword *SprSavePtr = NULL;
  55.  
  56.     Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  57.     ior->io_Command = IND_ADDHANDLER;
  58.     ior->io_Data = (APTR)&addhand;
  59.     DoIO(ior);
  60.     for (;;) {
  61.         register long sigs = Wait(SBF_C|(1<<dms->Port.mp_SigBit));
  62.         if (sigs & (1 << dms->Port.mp_SigBit)) {
  63.         register MSG *msg;
  64.         while (msg = GetMsg(&dms->Port)) {
  65.             switch((long)msg->mn_Node.ln_Name) {
  66.             case REQ_SCREENON:
  67.             if (scr)
  68.                 CloseScreen(scr);
  69.             scr = NULL;
  70.             break;
  71.             case REQ_SCREENOFF:
  72.             if (scr) {
  73.                 ScreenToFront(scr);
  74.             } else {
  75.                 if (scr = OpenScreen(&Ns))
  76.                 SetRGB4(&scr->ViewPort, 0, 0, 0, 0);
  77.             }
  78.             break;
  79.             case REQ_MOUSEON:
  80.             if (SprSavePtr) {
  81.                 register COPINIT *ci = GfxBase->copinit;
  82.                 ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
  83.                 ci->sprstrtup[3] = (uword)(long)SprSavePtr;
  84.                 SprSavePtr = NULL;
  85.             }
  86.             break;
  87.             case REQ_MOUSEOFF:
  88.             {
  89.                 register COPINIT *ci = GfxBase->copinit;
  90.                 if (!SprSavePtr)
  91.                 SprSavePtr = (uword *)((ci->sprstrtup[1] << 16) | ci->sprstrtup[3]);
  92.                 ci->sprstrtup[1] = (ulong)dms->NoSprData >> 16;
  93.                 ci->sprstrtup[3] = (uword)(long)dms->NoSprData;
  94.             }
  95.             break;
  96.             case REQ_DOCMD:
  97.             {
  98.                 long fh = Open("nil:", 1006);
  99.                 Execute(dms->Cmd, NULL, fh);
  100.                 if (fh)
  101.                 Close(fh);
  102.             }
  103.             break;
  104.             }
  105.             FreeMem(msg, msg->mn_Length);
  106.         }
  107.         }
  108.         if (sigs & SBF_C)
  109.         break;
  110.     }
  111.     Forbid();
  112.     ior->io_Command = IND_REMHANDLER;
  113.     ior->io_Data = (APTR)&addhand;
  114.     DoIO(ior);
  115.     Permit();
  116.     CloseDevice(ior);
  117.     {
  118.         register MSG *msg;
  119.         while (msg = GetMsg(&dms->Port))
  120.         FreeMem(msg, msg->mn_Length);
  121.     }
  122.     if (scr)
  123.         CloseScreen(scr);
  124.     if (SprSavePtr) {
  125.         register COPINIT *ci = GfxBase->copinit;
  126.         ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
  127.         ci->sprstrtup[3] = (uword)(long)SprSavePtr;
  128.         SprSavePtr = NULL;
  129.     }
  130.     }
  131.     goto closedown;
  132. startupfail:
  133.     dms->StartupError = 1;
  134.     Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  135.     Wait(SBF_C);
  136. closedown:
  137.     DeleteStdIO(ior);
  138. fail:
  139.     if (IntuitionBase)
  140.     CloseLibrary(IntuitionBase);
  141.     if (GfxBase)
  142.     CloseLibrary(GfxBase);
  143.     if (LayersBase)
  144.     CloseLibrary(LayersBase);
  145.     Forbid();
  146.     Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  147. }
  148.  
  149.  
  150. #asm
  151.         ;    A0 = pointer to event linked list
  152.         ;    A1 = pointer to my data segment
  153.         ;    return new event linked list in D0
  154.  
  155.         public  _CHandler
  156.  
  157. _handler:
  158.         movem.l D2/D3/A0/A1/A4/A6,-(sp)
  159.         jsr     _CHandler
  160.         movem.l (sp)+,D2/D3/A0/A1/A4/A6
  161.         rts
  162.  
  163. #endasm
  164.  
  165. /*
  166.  *  (1) Accellerate mouse movements.
  167.  *  (2) Auto-Select window
  168.  */
  169.  
  170. IE *
  171. CHandler(scr0, scr1, Ev)
  172. IE *Ev;
  173. {
  174.     register IE *ev;
  175.     register DMS *dms;
  176.     static char STimedout;
  177.     static char MTimedout;
  178.     static long STime, MTime;
  179.  
  180.     geta4();
  181.     dms = Dms;
  182.     for (ev = Ev; ev; ev = Ev->ie_NextEvent) {
  183.     switch(ev->ie_Class) {
  184.     case IECLASS_RAWMOUSE:
  185.         /*
  186.          *    Mouse events restore both the screen and mouse pointer.
  187.          */
  188.  
  189.         STime = ev->ie_TimeStamp.tv_secs + dms->STo;
  190.         MTime = ev->ie_TimeStamp.tv_secs + dms->MTo;
  191.         if (STimedout)
  192.         sendrequest(REQ_SCREENON);
  193.         if (MTimedout)
  194.         sendrequest(REQ_MOUSEON);
  195.         STimedout = MTimedout = 0;
  196.  
  197.         /*
  198.          *    Mouse Acceleration
  199.          */
  200.         {
  201.         register short n;
  202.         register short s;
  203.  
  204.         if (dms->Acc != 1) {
  205.             n = ev->ie_X;
  206.             s = 1;
  207.             if (n < 0) {
  208.             n = -n;
  209.             s = -1;
  210.             }
  211.             if (n > dms->AThresh)
  212.             ev->ie_X = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
  213.             n = ev->ie_Y;
  214.             s = 1;
  215.             if (n < 0) {
  216.             n = -n;
  217.             s = -1;
  218.             }
  219.             if (n > dms->AThresh)
  220.             ev->ie_Y = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
  221.         }
  222.         }
  223.  
  224.         /*
  225.          *    Auto Activate and LMB (win/scrn front/bak)
  226.          */
  227.         if (dms->AAEnable | dms->LMBEnable) {
  228.         register LAYER *layer;
  229.  
  230.         Forbid();
  231.         layer = WhichMouseLayer();
  232.         if (dms->LMBEnable && ev->ie_Code == IECODE_RBUTTON && (ev->ie_Qualifier & dms->RQual)) {
  233.             register WIN *win;
  234.             if (layer && (win = (WIN *)layer->Window) && !(win->Flags & BACKDROP) && (win->NextWindow || win->WScreen->FirstWindow != win))
  235.             WindowToBack(layer->Window);
  236.             else if (IBASE->FirstScreen)
  237.             ScreenToBack(IBASE->FirstScreen);
  238.             ev->ie_Class = IECLASS_NULL;    /*    remove event    */
  239.         }
  240.         if (layer && layer->Window) {
  241.             if (dms->LMBEnable && ev->ie_Code == IECODE_LBUTTON && layer->ClipRect && layer->ClipRect->Next) {
  242.             /*
  243.              *  Note: Case where it is the 'first' click in a series, where dms->CTime is
  244.              *      garbage, works properly no matter what DoubleClick returns.
  245.              */
  246.             if ((APTR)dms->CWin == layer->Window && DoubleClick(dms->CTime.tv_secs, dms->CTime.tv_micro, ev->ie_TimeStamp.tv_secs, ev->ie_TimeStamp.tv_micro))
  247.                 --dms->CLeft;
  248.             else
  249.                 dms->CLeft = dms->Clicks - 1;
  250.             dms->CTime = ev->ie_TimeStamp;
  251.             dms->CWin = (WIN *)layer->Window;
  252.             if (dms->CLeft == 0) {
  253.                 dms->CLeft = dms->Clicks;
  254.                 WindowToFront(layer->Window);
  255.             }
  256.             }
  257.             if (dms->AAEnable && ev->ie_Code == IECODE_NOBUTTON && !(ev->ie_Qualifier & 0x7000) && layer->Window != IBASE->ActiveWindow)
  258.             ActivateWindow(layer->Window);
  259.         }
  260.         Permit();
  261.         }
  262.         break;
  263.     case IECLASS_RAWKEY:
  264.         /*
  265.          *    Keyboard events will kill the screen timeout but not
  266.          *    the mouse timeout.
  267.          */
  268.         {
  269.         register LAYER *layer;
  270.  
  271.         Forbid();
  272.         layer = WhichMouseLayer();
  273.         if (layer && layer->Window) {
  274.             if (dms->AAEnable && layer->Window != IBASE->ActiveWindow)
  275.             ActivateWindow(layer->Window);
  276.         }
  277.         Permit();
  278.         }
  279.         STime = ev->ie_TimeStamp.tv_secs + dms->STo;
  280.         if (STimedout)
  281.         sendrequest(REQ_SCREENON);
  282.         STimedout = 0;
  283.         if (ev->ie_Code == dms->Code && ev->ie_Qualifier == dms->Qual) {
  284.         sendrequest(REQ_DOCMD);
  285.         ev->ie_Class = IECLASS_NULL;    /*  remove event    */
  286.         }
  287.         break;
  288.     case IECLASS_TIMER:
  289.         /*
  290.          *    On a timer event, if timeout has occured execute the operation
  291.          *    and reset the timeout.    Note that this will cause continuous
  292.          *    timeouts every STo and MTo seconds... required because at any
  293.          *    time Intuition might turn the mouse back on or open a screen or
  294.          *    something and I want the blanker's to work in the long run.
  295.          */
  296.         {
  297.         register long old;
  298.         if (dms->STo && (old = STime - ev->ie_TimeStamp.tv_secs) < 0) {
  299.             STime = ev->ie_TimeStamp.tv_secs + dms->STo + 10;
  300.             STimedout = 1;
  301.             if (old > -10)
  302.             sendrequest(REQ_SCREENOFF);
  303.         }
  304.         if (dms->MTo && (old = MTime - ev->ie_TimeStamp.tv_secs) < 0) {
  305.             MTime = ev->ie_TimeStamp.tv_secs + dms->MTo + 1;
  306.             MTimedout = 1;
  307.             if (old > -10)
  308.             sendrequest(REQ_MOUSEOFF);
  309.         }
  310.         }
  311.         break;
  312.     }
  313.     }
  314.     return(Ev);
  315. }
  316.  
  317.  
  318. sendrequest(req)
  319. long req;
  320. {
  321.     register MSG *msg = AllocMem(sizeof(MSG), MEMF_PUBLIC);
  322.  
  323.     if (msg) {
  324.     msg->mn_Node.ln_Name = (char *)req;
  325.     msg->mn_ReplyPort = NULL;
  326.     msg->mn_Length = sizeof(MSG);
  327.     PutMsg(&Dms->Port, msg);
  328.     }
  329. }
  330.  
  331. LAYER *
  332. WhichMouseLayer()
  333. {
  334.     register struct IntuitionBase *ib = IBASE;
  335.     register LAYER *layer = NULL;
  336.     register SCR *scr = ib->FirstScreen;
  337.  
  338.     for (scr = ib->FirstScreen; scr; scr = scr->NextScreen) {
  339.     register short mousey = ib->MouseY;
  340.     if (!(scr->ViewPort.Modes & LACE))
  341.         mousey >>= 1;
  342.     if (layer = WhichLayer(&scr->LayerInfo, ib->MouseX, mousey - scr->ViewPort.DyOffset))
  343.         break;
  344.     if (mousey >= scr->ViewPort.DyOffset)
  345.         break;
  346.     }
  347.     return(layer);
  348. }
  349.